package com.matrix.framework.audit.service;

import com.matrix.framework.audit.data.AuditLogPo;
import com.matrix.framework.audit.data.AuditLogVo;
import com.matrix.framework.audit.repositories.AuditLogRepository;
import com.matrix.framework.core.common.utils.DateTime;
import com.matrix.framework.core.i18n.I18n;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 审计日志服务
 *
 * Copyright © 海平面工作室 版权所有
 *
 * @Author: Leo
 * @Create: 2024/10/3 11:15
 * @Since 1.0
 */
@Service
public class AuditLogService {

    private final AuditLogRepository auditLogRepository;

    public AuditLogService(AuditLogRepository auditLogRepository) {
        this.auditLogRepository = auditLogRepository;
    }

    public Mono<Map<String, Object>> findAll(PageRequest pageable, String search) {
        int limit = pageable.getPageSize();
        long offset = pageable.getOffset();

        Flux<AuditLogPo> logs;
        Mono<Long> total;

        if (search != null && !search.isEmpty()) {
            logs = auditLogRepository.findAllWithSearch(search, limit, offset);
            total = auditLogRepository.countWithSearch(search);
        } else {
            logs = auditLogRepository.findAllWithPagination(limit, offset);
            total = auditLogRepository.countAll();
        }

        return logs.map(log -> {
                    AuditLogVo vo = new AuditLogVo();
                    vo.setId(log.getId());
                    vo.setUsername(log.getUsername());
                    vo.setModule(log.getModule());
                    vo.setAction(log.getAction());
                    vo.setCreateTime(DateTime.format(log.getTimestamp()));
                    vo.setDetails(log.getDetails());
                    return vo;
                }).collectList()
                .flatMap(list -> total.map(count -> {
                    Map<String, Object> result = new HashMap<>();
                    result.put("items", list);
                    result.put("total", count);
                    return result;
                }));
    }

    public Flux<AuditLogPo> findAll() {
        return auditLogRepository.findAll()
                .map(log -> {
                    log.setDetails(I18n.getMessage(log.getAction()));
                    return log;
                });
    }

    public Mono<AuditLogPo> findById(Long id) {
        return auditLogRepository.findById(id);
    }

    public Mono<AuditLogPo> save(AuditLogPo auditLog) {
        auditLog.setTimestamp(System.currentTimeMillis());
        return auditLogRepository.save(auditLog);
    }

    public Mono<Void> deleteById(Long id) {
        return auditLogRepository.deleteById(id);
    }
} 